<!DOCTYPE HTML>
<html>
<head>
  <meta charset="utf-8">
  <meta name="variant" content="">
  <meta name="variant" content="?keep-promise">
  <title>IdlInterface.prototype.test_to_json_operation()</title>
  <script src="../../../../variants.js"></script>
  <script src="/resources/testharness.js"></script>
  <script src="/resources/testharnessreport.js"></script>
  <script src="/resources/WebIDLParser.js"></script>
  <script src="/resources/idlharness.js"></script>
  <script src="../../../../idl-helper.js"></script>
</head>
<body>
<script>
    "use strict";
    function wrap(member, obj) {
        function F(obj) {
            this._obj = obj;
        }

        F.prototype.toJSON = function() {
            return this._obj;
        }
        Object.defineProperty(F, 'name', { value: member.name });
        return new F(obj);
    }

    var i, obj;
    i = interfaceFrom("interface A { [Default] object toJSON(); attribute long foo; };");
    i.test_to_json_operation("object", wrap(i, { foo: 123 }), i.members[0]);

    // should fail (wrong type)
    i = interfaceFrom("interface B { [Default] object toJSON(); attribute long foo; };");
    i.test_to_json_operation("object", wrap(i, { foo: "a value" }), i.members[0]);

    // should handle extraneous attributes (e.g. from an extension specification)
    i = interfaceFrom("interface C { [Default] object toJSON(); attribute long foo; };");
    i.test_to_json_operation("object", wrap(i, { foo: 123, bar: 456 }), i.members[0]);

    // should fail (missing property)
    i = interfaceFrom("interface D { [Default] object toJSON(); attribute long foo; };");
    i.test_to_json_operation("object", wrap(i, { }), i.members[0]);

    // should fail (should be writable)
    obj = Object.defineProperties({}, { foo: {
        writable: false,
        enumerable: true,
        configurable: true,
        value: 123
    }});
    i = interfaceFrom("interface F { [Default] object toJSON(); attribute long foo; };");
    i.test_to_json_operation("object", wrap(i, obj), i.members[0]);

    // should fail (should be enumerable)
    obj = Object.defineProperties({}, { foo: {
        writable: true,
        enumerable: false,
        configurable: true,
        value: 123
    }});
    i = interfaceFrom("interface G { [Default] object toJSON(); attribute long foo; };");
    i.test_to_json_operation("object", wrap(i, obj), i.members[0]);

    // should fail (should be configurable)
    obj = Object.defineProperties({}, { foo: {
        writable: true,
        enumerable: true,
        configurable: false,
        value: 123
    }});
    i = interfaceFrom("interface H { [Default] object toJSON(); attribute long foo; };");
    i.test_to_json_operation("object", wrap(i, obj), i.members[0]);

    var idl = new IdlArray();
    idl.add_idls("interface I : J { [Default] object toJSON(); attribute long foo; };");
    idl.add_idls("interface J { [Default] object toJSON(); attribute DOMString foo;};");
    var i = idl.members.I;
    i.test_to_json_operation("object", wrap(i, { foo: 123 }), i.members[0]);

    i = interfaceFrom("interface K { [Default] object toJSON(); };");
    i.test_to_json_operation("object", wrap(i, {}), i.members[0]);

    i = interfaceFrom("interface L { DOMString toJSON(); };");
    i.test_to_json_operation("object", wrap(i, "a string"), i.members[0]);

    // should fail (wrong output type)
    i = interfaceFrom("interface M { DOMString toJSON(); };");
    i.test_to_json_operation("object", wrap(i, {}), i.members[0]);

    // should fail (not an IDL type)
    i = interfaceFrom("interface N { DOMException toJSON(); };");
    i.test_to_json_operation("object", wrap(i, {}), i.members[0]);
</script>
<script type="text/json" id="expected">
    {
        "summarized_status": {
            "message": null,
            "status_string": "OK"
        },
        "summarized_tests": [
            {
                "message": null,
                "name": "A interface: default toJSON operation on object",
                "properties": {},
                "status_string": "PASS"
            },
            {
                "message": "assert_equals: expected \"number\" but got \"string\"",
                "name": "B interface: default toJSON operation on object",
                "properties": {},
                "status_string": "FAIL"
            },
            {
                "message": null,
                "name": "C interface: default toJSON operation on object",
                "properties": {},
                "status_string": "PASS"
            },
            {
                "message": "assert_true: property \"foo\" should be present in the output of D.prototype.toJSON() expected true got false",
                "name": "D interface: default toJSON operation on object",
                "properties": {},
                "status_string": "FAIL"
            },
            {
                "message": "assert_true: property foo should be writable expected true got false",
                "name": "F interface: default toJSON operation on object",
                "properties": {},
                "status_string": "FAIL"
            },
            {
                "message": "assert_true: property foo should be enumerable expected true got false",
                "name": "G interface: default toJSON operation on object",
                "properties": {},
                "status_string": "FAIL"
            },
            {
                "message": "assert_true: property foo should be configurable expected true got false",
                "name": "H interface: default toJSON operation on object",
                "properties": {},
                "status_string": "FAIL"
            },
            {
                "message": null,
                "name": "I interface: default toJSON operation on object",
                "properties": {},
                "status_string": "PASS"
            },
            {
                "message": null,
                "name": "K interface: default toJSON operation on object",
                "properties": {},
                "status_string": "PASS"
            },
            {
                "message": null,
                "name": "L interface: toJSON operation on object",
                "properties": {},
                "status_string": "PASS"
            },
            {
                "message": "assert_equals: expected \"string\" but got \"object\"",
                "name": "M interface: toJSON operation on object",
                "properties": {},
                "status_string": "FAIL"
            },
            {
                "message": "assert_true: {\"type\":\"return-type\",\"extAttrs\":[],\"generic\":\"\",\"nullable\":false,\"union\":false,\"idlType\":\"DOMException\"} is not an appropriate return value for the toJSON operation of N expected true got false",
                "name": "N interface: toJSON operation on object",
                "properties": {},
                "status_string": "FAIL"
            }
        ],
        "type": "complete"
    }
</script>
</body>
</html>
